/**
 * constantRoutes 常规路由，不需要权限即可访问
 * asyncRoutes 需要访问权限的路由
 * notFoundRoutes 404路由
 * resetRouter 重置路由的方法
 */
import { asyncRoutes, constantRoutes, notFoundRoutes, resetRouter } from '@/router'
import API from '@/assets/http/apiUrl'
import Request from '@/assets/http'


const permission = {
  state: {
    routes: [],
    addRoutes: [] // 异步加载的路由
  },

  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
      console.log("all",  state.routes)
    }
  },

  actions: {
    // 获取动态路由
    GenerateRoutes({ commit }) {
      resetRouter() // 先初始化路由
      return new Promise((resolve, reject) => {
          Request.httpRequest({
            method: 'post',
            url: API.GetPermissionData,
            noLoading: true,
            params: {},
            success: (res) => {
              let accessedRoutes = []
              let  loadAsyncMeun = []
              let  asyncMeuns= res
              //组装路由
              generaMenu(loadAsyncMeun, asyncMeuns)
              // 匹配前端路由和后台返回的菜单
              accessedRoutes = filterAsyncRoutes([...asyncRoutes,...loadAsyncMeun], ["admin"])
              // 重定向404的匹配规则需要在整个完整路由定义的最后面，否则刷新会出错。
              accessedRoutes.push(...notFoundRoutes)
              commit('SET_ROUTES', accessedRoutes)
              resolve(accessedRoutes)
            },
            error: res => {
              reject(res)
            }
          })
        
      })
    }
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * 匹配后台返回的菜单信息和前端定义的路由
 * @param routes 前端定义好的异步路由
 * @param menus 后台返回的菜单
 */
 export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

/**
 * Use meta.role to determine if the current user has permission
 * @param menus 后台返回的菜单
 * @param route 前端定义好的异步路由中的项
 */
 function hasPermission(roles, route) { 
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * 后台查询的菜单数据拼装成路由格式的数据
 * @param routes
 */
 export  function generaMenu(routes, resData) {
  
  resData.forEach(item => {
    let menu = {
      path: item.path,
      component: item.component === '#' ?() => import('@/layout') :  resolve => void require([`@/views${item.component}`], resolve),
      children: [],
      name: item.name,
      meta:{... item.meta}
    }
    item.hidden ? menu['hidden'] = item.hidden : null
    item.redirect ? menu['redirect'] = item.redirect : null;
    (item.meta && item.meta.noCache) ? menu.meta['noCache'] = item.meta.noCache : null
    if (item.children) {
      generaMenu(menu.children, item.children)
    }

    console.log("routesPUSH",  routes, "MENU", menu)

    routes.push(menu)
  })
}

export default permission
